"""数据存储服务 - 保存到 PostgreSQL"""
import logging
import hashlib
from typing import List, Dict, Optional, Any
from datetime import datetime
from sqlalchemy.exc import IntegrityError

from app.database.connection import get_db_session
from app.database.models import ExamQuestion, SearchRecord, QuestionSource

logger = logging.getLogger(__name__)


class StorageService:
    """数据存储服务"""
    
    def generate_question_id(self, content: str, source_url: str) -> str:
        """生成题目唯一ID"""
        # 使用内容和URL的哈希值生成ID
        combined = f"{content}_{source_url}"
        hash_obj = hashlib.md5(combined.encode('utf-8'))
        return f"exam_{hash_obj.hexdigest()[:12]}"
    
    def save_question(self, question_data: Dict[str, Any]) -> Optional[ExamQuestion]:
        """
        保存单个题目到数据库
        
        Args:
            question_data: 题目数据字典
            
        Returns:
            保存的题目对象，如果失败返回 None
        """
        try:
            with get_db_session() as db:
                # 生成题目ID
                question_id = self.generate_question_id(
                    question_data.get('content', ''),
                    question_data.get('source_url', '')
                )
                
                # 检查是否已存在
                existing = db.query(ExamQuestion).filter(
                    ExamQuestion.question_id == question_id
                ).first()
                
                if existing:
                    logger.debug(f"题目已存在: {question_id}")
                    return existing
                
                # 创建新题目
                exam_question = ExamQuestion(
                    question_id=question_id,
                    content=question_data.get('content', ''),
                    question_type=question_data.get('question_type', 'single_choice'),
                    options=question_data.get('options', []),
                    correct_answer=question_data.get('correct_answer', ''),
                    explanation=question_data.get('explanation', ''),
                    subject=question_data.get('subject', ''),
                    category=question_data.get('category', ''),
                    difficulty=question_data.get('difficulty', 'medium'),
                    knowledge_points=question_data.get('knowledge_points', []),
                    year=question_data.get('year'),
                    exam_type=question_data.get('exam_type', '客观题'),
                    source_url=question_data.get('source_url', ''),
                    source_site=question_data.get('source_site', ''),
                    parsed_content=question_data.get('parsed_content', {}),
                    entities=question_data.get('entities', []),
                    classification=question_data.get('classification', {}),
                    is_verified=False,
                    is_active=True
                )
                
                db.add(exam_question)
                db.commit()
                db.refresh(exam_question)
                
                logger.info(f"题目保存成功: {question_id}")
                return exam_question
                
        except IntegrityError as e:
            logger.warning(f"题目保存失败（可能已存在）: {str(e)}")
            return None
        except Exception as e:
            logger.error(f"题目保存失败: {str(e)}", exc_info=True)
            return None
    
    def save_questions_batch(self, questions: List[Dict[str, Any]]) -> Dict[str, int]:
        """
        批量保存题目
        
        Args:
            questions: 题目数据列表
            
        Returns:
            保存统计信息
        """
        stats = {
            'total': len(questions),
            'saved': 0,
            'skipped': 0,
            'failed': 0
        }
        
        for question_data in questions:
            result = self.save_question(question_data)
            if result:
                stats['saved'] += 1
            elif result is None:
                stats['skipped'] += 1
            else:
                stats['failed'] += 1
        
        logger.info(f"批量保存完成: {stats}")
        return stats
    
    def create_search_record(
        self,
        search_query: str,
        search_type: str,
        year_range: str
    ) -> SearchRecord:
        """
        创建搜索记录
        
        Args:
            search_query: 搜索关键词
            search_type: 搜索类型
            year_range: 年份范围
            
        Returns:
            搜索记录对象
        """
        try:
            with get_db_session() as db:
                search_record = SearchRecord(
                    search_query=search_query,
                    search_type=search_type,
                    year_range=year_range,
                    status='pending'
                )
                
                db.add(search_record)
                db.commit()
                db.refresh(search_record)
                
                return search_record
        except Exception as e:
            logger.error(f"创建搜索记录失败: {str(e)}", exc_info=True)
            raise
    
    def update_search_record(
        self,
        record_id: int,
        status: str,
        total_found: int = 0,
        total_saved: int = 0,
        error_message: Optional[str] = None
    ):
        """
        更新搜索记录
        
        Args:
            record_id: 记录ID
            status: 状态
            total_found: 找到的题目总数
            total_saved: 成功保存的题目数
            error_message: 错误信息
        """
        try:
            with get_db_session() as db:
                record = db.query(SearchRecord).filter(
                    SearchRecord.id == record_id
                ).first()
                
                if record:
                    record.status = status
                    record.total_found = total_found
                    record.total_saved = total_saved
                    if error_message:
                        record.error_message = error_message
                    if status == 'completed' or status == 'failed':
                        record.completed_at = datetime.now()
                    
                    db.commit()
        except Exception as e:
            logger.error(f"更新搜索记录失败: {str(e)}", exc_info=True)
    
    def get_question_by_id(self, question_id: str) -> Optional[ExamQuestion]:
        """根据ID获取题目"""
        try:
            with get_db_session() as db:
                return db.query(ExamQuestion).filter(
                    ExamQuestion.question_id == question_id
                ).first()
        except Exception as e:
            logger.error(f"获取题目失败: {str(e)}")
            return None
    
    def get_questions_by_year(self, year: int, limit: int = 100) -> List[ExamQuestion]:
        """根据年份获取题目"""
        try:
            with get_db_session() as db:
                return db.query(ExamQuestion).filter(
                    ExamQuestion.year == year,
                    ExamQuestion.is_active == True
                ).limit(limit).all()
        except Exception as e:
            logger.error(f"获取题目失败: {str(e)}")
            return []
    
    def get_questions_by_subject(self, subject: str, limit: int = 100) -> List[ExamQuestion]:
        """根据科目获取题目"""
        try:
            with get_db_session() as db:
                return db.query(ExamQuestion).filter(
                    ExamQuestion.subject == subject,
                    ExamQuestion.is_active == True
                ).limit(limit).all()
        except Exception as e:
            logger.error(f"获取题目失败: {str(e)}")
            return []

